#include "net.h"
#include <poll.h>
#define MAX_SOCK_FD 1024

int main(int argc, char *argv[])
{
	int i, j, ret, fd, newfd;
	Addr_in clientaddr;
	socklen_t clientlen = sizeof(Addr_in);
	struct pollfd fds[MAX_SOCK_FD] = {};
	nfds_t nfds;
	/*检查参数，小于3个 直接退出进程*/
	Argment(argc, argv);
	/*创建已设置监听模式的套接字*/
	fd = CreateSocket(argv);

	fds[0].fd = fd;
	fds[0].events = POLLIN;
	nfds = 1;

	while(1){
		//当poll返回值大于0，其值表明有多少文件描述符已到
		if( (ret = poll(fds, nfds, -1)) < 0)
			ErrExit("select");

		if(fds[0].revents == POLLIN){
			//接收客户端连接，并生成新的文件描述符	
			if( (newfd = accept(fd, (Addr *)&clientaddr, &clientlen) ) < 0)
				perror("accept");
			printf("[%s:%d]已建立连接，文件描述符为：%d\n", 
					inet_ntoa(clientaddr.sin_addr), ntohs(clientaddr.sin_port), newfd);
			fds[nfds].fd = newfd;
			fds[nfds++].events = POLLIN;
		}else{
			//处理客户端数据
			for(i = 1; i < nfds; i++){
				if(fds[i].revents == POLLIN){
					//该文件描述符来了数据
					if( DataHandle(fds[i].fd) <= 0){
						if( getpeername(fds[i].fd, (Addr *)&clientaddr, &clientlen) )
							perror("getpeername");
						printf("[%s:%d]断开连接，文件描述符为: %d\n", 
								inet_ntoa(clientaddr.sin_addr), ntohs(clientaddr.sin_port), fds[i].fd);
						close(fds[i].fd);
						//由于poll维护的是一个顺序表，所以杀掉一个连接，要将后面数据往前移
						for(j = i; j < nfds - 1; j++){
							fds[j] = fds[j+1];
						}
						nfds--;
						i--;
					}
				}
			}
		}
	}
	close(fd);
	return 0;
}

